/***********************************************
 * Open a Server List module
 * @return Void
 ***********************************************/
function server_list(NeedToopenOpts) {
    new modServerList(NeedToopenOpts);
}


/***********************************************
 * Open a Modal Help Page
 * @return Void
 ***********************************************/
function wfc_show_help_page(callerthis) {
	return new modModalHelpPage(callerthis);
}

/***********************************************
 * Must call this function in widget showSettings function
 * @ Parameter callerthis (In): widget this
 * @ Parameter settingbox (In) : widget setting box
 * @ Parameter toggleFunction (In) : implementation for top down style settingbox function
 * @return modal window widget or widget this
 * example: this.widgetSetting=wfc_widget_setting(this,this.settingsBox,wfc_widget_setting_default_toggle.bind(this));
 ***********************************************/
function wfc_widget_setting(callerthis,settingbox,toggleFunction) {
	if(!callerthis || !settingbox || !toggleFunction) return undefined;
	if(custom_options.use_modal_widget_setting)
	{
		settingbox.setStyle('display' , 'block');	
		return new modModalWidgetSetting(callerthis,settingbox);
	}
	else
	{
		if(!$chk(settingbox.getParent()))
			settingbox.inject(callerthis.contentBox,'top');
		toggleFunction();
		return callerthis;
	}
}

function wfc_widget_setting_default_toggle(){
	if(!this.settingsBox) return;
	if(this.settingsBox.getStyle('display') == 'none') 
		this.settingsBox.setStyle('display' , 'block');	
	else 
		this.settingsBox.setStyle('display' , 'none');		
}

String.prototype.wordWrap = function(m, b, c){
    var j, s, r = this.split("\n");
    if(m > 0) for(var i=0; i<r.length; i++){
        for(s = r[i], r[i] = ""; s.length > m;
            j = c ? m : (j = s.substr(0, m).match(/\S*$/)).input.length - j[0].length
            || m,
            r[i] += s.substr(0, j) + ((s = s.substr(j)).length ? b : "")
        );
        r[i] += s;
    }
    return r.join("\n");
};


String.repeat = function(chr,count)
{
    var str = "";
    for(var x=0;x<count;x++) {str += chr};
    return str;
}

String.prototype.padL = function(width,pad)
{
    if (!width ||width<1)
        return this;

    if (!pad) pad=" ";
    var length = width - this.length
    if (length < 1) return this.substr(0,width);

    return (String.repeat(pad,length) + this).substr(0,width);
}

String.prototype.padR = function(width,pad)
{
    if (!width || width<1)
        return this;

    if (!pad) pad=" ";
    var length = width - this.length
    if (length < 1) this.substr(0,width);

    return (this + String.repeat(pad,length)).substr(0,width);
}

var StringBuffer = function() {
	this.buffer = [];
	this.index = 0;
};

StringBuffer.prototype = {
	append: function(s) {
		this.buffer[this.index] = s;
		this.index += 1;
		return this;
	},

	toString: function() {
		return this.buffer.join('');
	}
};

Date.prototype.formatDate = function(format)
{
    var date = this;
    if (!format)
      format="MM/dd/yyyy";

    var month = date.getMonth() + 1;
    var year = date.getFullYear();

    format = format.replace("MM",month.toString().padL(2,"0"));

    if (format.indexOf("yyyy") > -1)
        format = format.replace("yyyy",year.toString());
    else if (format.indexOf("yy") > -1)
        format = format.replace("yy",year.toString().substr(2,2));

    format = format.replace("dd",date.getDate().toString().padL(2,"0"));


    var hours = date.getHours();
    var hasAMPM = false;
    if (format.indexOf("t") > -1)
    {
       hasAMPM = true;
       if (hours > 11)
        format = format.replace("t","pm")
       else
        format = format.replace("t","am")
    }

    if (format.indexOf("hh") > -1) {
        if (hours > 12) hours = hours - 12;
        if (hours == 0) hours = 12;
        format = format.replace("hh",hours.toString().padL(2,"0"));  
    }
    if (format.indexOf("HH") > -1) {
        if(!hasAMPM) {
            format = format.replace("HH",hours.toString().padL(2,"0")); 
        } else {
            if (hours > 12) hours = hours - 12;
            if (hours == 0) hours = 12;
            format = format.replace("HH",hours.toString().padL(2,"0"));  
        }
    }
    if (format.indexOf("mm") > -1)
       format = format.replace("mm",date.getMinutes().toString().padL(2,"0"));
    if (format.indexOf("ss") > -1)
       format = format.replace("ss",date.getSeconds().toString().padL(2,"0"));

    if(format.indexOf("O") > -1)
        format=format.replace("O",(date.getTimezoneOffset() < 0 ? '-' : '+') + (date.getTimezoneOffset() / 60 < 10 ? '0' : '') + (date.getTimezoneOffset() / 60) );

    return format;
}

function initXMLDOM(xmlString){
        // Mozilla and Netscape browsers
        var doc=null;
        if (document.implementation.createDocument) {
                var parser = new DOMParser();
        doc = parser.parseFromString(xmlString, "text/xml");
                // MSIE
                } else if (window.ActiveXObject) {
                        doc = new ActiveXObject("Microsoft.XMLDOM");
                        doc.async="false";
                        doc.loadXML(xmlString);
                }
        return doc;
}

function openOpts(){
    var div = $('dvLogin');
    var nt = parseInt(div.offsetHeight,10) + 3;
    div.tween('top', div.getStyle('top')=='-1px'? -nt + 'px':'-1px');
    $('opt_link').blur();
}

// Terrence 5/27/09
// Provide a function allow user to fire events to all active widgets
function wfc_fireEventToAllActiveWidgets(myevent,param)
{
    if(!wfc_mainScreen) return;
	if(!wfc_mainScreen.currActive) return;
	if(!$chk($('contenttable'+wfc_mainScreen.currActive))) return;
	
	var blocks = $('contenttable'+wfc_mainScreen.currActive).getElements('div[id^=fdiv]');
	var c = blocks.length;
	for(var i = 0 ; i < c ; i++){
		if( blocks[i].id != "fdiv" ) {
		    var numb = blocks[i].id.replace(/fdiv/i , "");
           var w = 'sbox' + numb;
			$(w).fireEvent(myevent, param);	
		}
	}
	//Roger 6/3/2009 each tab should set dirty flag
	if("AfterResize" == myevent)
	{
		if ($chk($('overlay')))
		{
			$('overlay').fireEvent(myevent, param);	
		}
		for(var i=1; i <= wfc_mainScreen.num_canvases; i++)
		{ 
			if($defined($('tab_box'+i))) 
			{
				if(parseInt(wfc_mainScreen.currActive)!=i)
				{
					$('tab_box'+i).setAttribute('NeedResize','1');
				}
			}
		}
		if (wfc_is_table_layout_style(currTabLayout)) return;
		if(window.ie6)
 		{
 			var cttdblocks = $('contenttable'+wfc_mainScreen.currActive).getElements('td[id^=cttd]');
 			var pagebodyWidth =$('tab_settings').getStyle('width');
    		var bodyWidth=pagebodyWidth.replace(/px/gi,'');
    		// get the total column number
    		var column_num = currTabLayout.split('-')[0];
    		var table=$('contenttable'+wfc_mainScreen.currActive);
    		var cellspacing = parseInt(table.getProperty('cellspacing'), 10)  * (parseInt(column_num,10)+1);
    		// sometimes we need minus width of scrollbar, sometimes not
    		var vertical_scroll = (document.body.clientHeight!=window.innerHeight) ? 0:18;
    		// This means each widget has 2px border width 
    		var border_w = 2; 
    		// correcting body width
    		bodyWidth = bodyWidth - cellspacing -  border_w * parseInt(column_num,10) - vertical_scroll;
 			for(var i = 0 ; i < cttdblocks.length ; i++){
 				var cttdnumb = cttdblocks[i].id;
 				var w0 = $(cttdnumb).getProperty('width'); // must use getProperty can't use getStyle. in percent
    			if (w0 == null) {
        			// this is 'all'! must calculate the width by 100% - others.
        			w0 = wfc_get_all_width(bodyWidth);
    			}
    			if (w0.indexOf("%") == -1) {
        			// not in percentage mode, just return the length;
        			w0=(w0)/bodyWidth+"%";
    			}
    			var min_width =wfc_pagebody_minwidth* w0.replace('%','')/100 -10; 
 				// img for setting min width 
				var imgspace=$(cttdnumb).getElement('.extraspace');
				if($chk(imgspace)) Element.remove(imgspace);
        		var img_min = new Element('img',{'class':'extraspace','src':'img/default/1space.gif', 'width':min_width, 'height':'1'}).injectInside($(cttdnumb));		
 			}
 		}
 		
    }	
}

// Terrence 05/27/09: Add resize event handler in body make after resize work.
// Algorithm.
// When receive body resize, setTimeout to wfc_AfterResize(). and also keep wfc_last_resizing_time.
// In wfc_AfterResize(), not always fire after resize event. only the (current time - 500) > wfc_last_resizing_time
var wfc_sizing = false;
var wfc_last_sizing_time = 0;
function wfc_AfterResize()
{
    // compare current time and last sizing time.
    // if the difference is larger than 500, then fire after resizing.
    var cd = new Date();
    var diff = cd.getTime() - wfc_last_sizing_time;
    
    if (diff > 500 && dragwhich==null) {
        // Yes, no resizing event sent for more than 500 ms.
        //console.log('After Resize');
        // notify  all widgets
        wfc_fireEventToAllActiveWidgets("AfterResize",null);
        
        // refresh event for messages - jeff 07/07/09
        wfc_MessageResize();
        
        // set wfc_sizing to false to allow new resize event from body        
        wfc_sizing = false;
    }
    else {
        // No, continue receive resizing events, don't execute AfterResize; wait another 500 ms.
        setTimeout("wfc_AfterResize()", 500);
    }
    
}

function wfc_BodyOnResize()
{
    // record current time as wfc_last_resizing_time.
    var cd = new Date();
    wfc_last_sizing_time = cd.getTime();
    
    // console.log('Common body MyOnResize');
    if (!wfc_sizing && dragwhich==null) {
        wfc_sizing = true;
        setTimeout("wfc_AfterResize()", 500);
        
        if(window.ie6)
        {   // the corner in ie6 sometimes looks odd
            var corner = $('tab_footbar').getElement('i');
            corner.setStyle('right', (corner.getParent().offsetWidth%2==0 ? 0 : 1) + 'px');
        }
    }
}

/*****
 - called by wfc_AfterResize()
 - Adjust all message boxes including global one 
 to solve the icon show/hide problem in different width
 *****/
function wfc_MessageResize(){ 
    // make a fake div to find the height of one line
    var fake_div = new Element('div',{'style':'height:1.2em'}).inject(document.body);
    var oneline_height = fake_div.scrollHeight;
    
    // grab all message boxes
    var els = $(document).getElements('.message_content');
    els.each(function(el){ 
        if(el.parentNode.id=='messageGlobal') 
        {   // adjust global message box to keep it center
            var mbox = el.parentNode
            var bw = document.body.clientWidth;
			var mw = mbox.clientWidth;
            var new_w = (bw-mw)>0 ? (bw-mw):0
			mbox.setStyle('left', new_w/2 + 'px');
        }else
        {   // messages in widgets
            var icon_link = el.getFirst('a');
            if(icon_link.className=='icon_hide' && el.offsetHeight > oneline_height)
            {   // always show the icon link if message is opened
                // and contains multiple lines
                icon_link.setStyle('display','');
            }else 
            {
                // show/hide icon depends on if it's multiple line in document after resized 
                icon_link.setStyle('display',el.offsetHeight!=el.scrollHeight ?'':'none');
            }
        }
    });
    
    // kill fake 
    fake_div.destroy();
}

// for debug, use it just like firebug in IE
// Usage: console.log(arg1, arg2, .....)
if(!console ||!console.log) {
    var console = {};
    console.log = function (){
        var $cons = !$('console-debug') ? null : $('console-debug');
        if(!$cons){
            $cons = new Element ('textarea', // info cons
                { 'id':'console-debug',
                'style':
                'position:absolute;overflow: auto;'+
                'width: 280px; height: 100px;'+
                'right: 20px ; bottom: 25px;' +
                'padding:10px; background: #f0f0f0;'+
                'border :1px solid #999',
                'events':{'click':function(e){ this.value='';},
                    'dblclick':function(e){ this.style.display='none'; }
                }
            }).injectInside(document.body);
            var $cmd = new Element('input', {// CLI input
                'type' : 'text',
                'style': 'width:296px;position:absolute;height:18px;right:20px;bottom:4px;',
                'events': { 
                    'keyup':function(e){ if(e.key=='enter'&&this.value!='') { var c = this.value;
                    if(parseInt(c,10)==c) { console.log(c); return;}
                    try { console.log(eval(c));} 
                    catch(err) { console.log('|==== Error Input: ' + err.description + '====|')}
                    }},
                    'dblclick':function(e){ if($cons) {$cons.style.display=''} }
                }
            }).inject($cons, 'after');
        } else {        
            $cons.setStyle('display','inline');            
        }        
        for(var i=0,a=arguments[i]; i<arguments.length; i++){
            a = arguments[i];
            if(a&&a.nodeType==1){
                a = a.tagName + (a.id?'#'+a.id:'') + (a.className?'.'+a.className:'');
            }
            $cons.value =($cons.value +(i!=0?', ':'')+ a  );
        }
            $cons.value = ($cons.value + '\n' );
        $cons.scrollTop = ($cons.scrollHeight);
    }
}

//////////////////////////////////////////////////////////////////////////////////
// Terrence 12/01/09, for table style layout, 

// When user select a layout, clicn 'save'; this function will return which layout is selected
function wfc_getSelectedLayout() {
    for(var x=0; x<wfc_layoutList.layouts.length; x++) {
        var oneLayout = wfc_layoutList.layouts[x];
        if (!$defined(oneLayout)) break;
        // check this is selected of not.
        if ($chk($(oneLayout.id)) && $(oneLayout.id).checked == true) {
            return oneLayout.value; // find the checked one
        }
    }
    if (!$defined(oneLayout)) return "";
    return wfc_layoutList.layouts[0].value; // default return the first one.
}

// Given the table layout html file name, Ajax (sync mode) load in and return the text. 
// The layout file must be in layout folder.
function wfc_ajax_read_table_layout_file(theLayoutFile)
{
    var layout_table = "layout/" + theLayoutFile; 
    var javascript_url = homeBase + layout_table;
	var myRequest = new Request({
	                     method: 'get',
	                     url: javascript_url,
	                     async:false     // must us sync mode because must wait the layout in
	                }).send();
    if (myRequest.status == 200) {
        if ($defined(myRequest.response.text)) return myRequest.response.text;// Ajax return OK.
    }
    return undefined;   // fail to get the layout table
}

// Given curLayout, search all layout, find one, and set it checked.
// For display page setting (add or mondify).
function wfc_setLayoutListCheckedItem(curLayout)
{
    for(var x=0; x<wfc_layoutList.layouts.length; x++) {
        var oneLayout = wfc_layoutList.layouts[x];
        if (!$defined(oneLayout)) break;
        // match curLayout is the same as oneLayout.value or not
        if (oneLayout.value == curLayout)
            oneLayout.checked = true;
        else
            oneLayout.checked = false;
    }
}

// return the widget count of current active tab.
function wfc_get_active_tab_widget_count()
{
    return pgWidgetsTotal;
}

// return the total block (cell) count of current active tab.
function wfc_get_active_tab_total_block_count()
{
    if(!wfc_mainScreen) return 0;
	if(!wfc_mainScreen.currActive) return 0;
	if(!$chk($('contenttable'+wfc_mainScreen.currActive))) return 0;

    var count = 0;
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
        var c_string = "cttd" + wfc_mainScreen.currActive + iIndex;
        if ($defined($(c_string))) {
            count++;
        }
        else break;
    }
	return count;
}

// return the empty block (cell) array of current active tab.
function wfc_get_active_tab_empby_block_array()
{
    var blockArray = new Array();
    var a_Index = 0;
    // search all blocks.
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
        var c_string = "cttd" + wfc_mainScreen.currActive + iIndex;
        var e0 = $(c_string);
        if ($defined(e0)) {
            // check if e0 contains a DIV with id starts with sbox
            var xTemp = e0.getElements('div[id^=sbox]');
            if (xTemp.length == 0) {
                blockArray[a_Index] = iIndex;
                a_Index++;
            }
            
        }
        else break;
    }
	return blockArray;
}


// 2 different style layout:
// column layout: 1-0, 2-0, 3-0, ....
// table layout: table_x.html
function wfc_is_table_layout_style(layout)
{
    // if layout is start with "table...", then return true
    // else return false;
    var t = layout.substr(0, 1);
    t = t.toUpperCase();
    if (t == "T") {
        var t2 = layout.substr(0, 5);
        t2 = t2.toUpperCase();
        if (t2 == "TABLE") return true;
    }
    return false;
}

// check these 2 layouts are the same style (column or table style)
function wfc_is_different_layout_style(layout_1, layout_2)
{
    if (wfc_is_table_layout_style(layout_1))
        if (wfc_is_table_layout_style(layout_2)) return false;
        else return true;
    else if (wfc_is_table_layout_style(layout_2)) return true;
        else return false;
}

// save widgets (add widgets) for table layout style
// use col to store block id (for draw the widget in which block).
function wfc_saveWidgets_table_layout_style()
{
    var current_widget_count = wfc_get_active_tab_widget_count();
    var total_block_count = wfc_get_active_tab_total_block_count();
    var new_added_count = wfc_get_defined_entity(tempAdded);
    
    if (new_added_count <= 0) return;
    
    // if tempAdded.length + current_widget_count bigger than total_block_count then return;
    if (new_added_count + current_widget_count > total_block_count) {
        alert(lang.labelText('too_many_widgets_add_into_this_page'));
        return;
    }
    
    var empty_block_array = wfc_get_active_tab_empby_block_array();
    if (empty_block_array.length <= 0) return;    // something wrong, no empty block.

        var a_Index = 0;
		var iJs="";
		var udataArray = new Array();
		var wdataArray = new Array();
		var nIdx = 0;

		var callAjax=false;
		if(tempAdded.length>0) 
		{ 	
			tempAdded.each(function(module, id)
			{  
				if(module !=undefined && module !="" && module !='undefined'){
					if(module!=0)
					{
						callAjax=true;
			 		    udataArray[nIdx] = {
			 		    	modname:module,
			 		    	column:empty_block_array[a_Index],           // block id
			 		    	order:nIdx+1,
			 		    	wid:pc, 
			 		    	showMin:widget_property.showMin, 
			 		    	showClose:widget_property.showClose, 
			 		    	showSetting:widget_property.showSetting,
			 		    	showHelp:widget_property.showHelp,  
			 		    	allowDrag:widget_property.allowDrag, 
			 		    	page:wfc_mainScreen.currActive
			 		    };
						//str1 += module+":"+pc+":"+ wfc_mainScreen.currActive +"|";   
						wdataArray[nIdx] = {modname:module, wid:pc, data:"", pid:wfc_mainScreen.currActive};
					 
						iJs +=module+','; 
						 
						pc++;
						nIdx++;
						a_Index++;
					}
				}
			}); 
			
			if(callAjax){
				$('reloadButton').setProperty('disabled', true);
				
				//find out what is the next col available.
                //useless code, should be removed
				sendData(dbHandler, JSON.encode({act:'addWidgets', pid: wfc_mainScreen.currActive, udata:udataArray, wdata:wdataArray, updatedOriginalUdata:[]}), addWidgetscallback,{iJs:iJs});
				
			}
			else
			{
				wfc_error_msg( lang.label('messege_reload') );
			}
		}
		else
		{
			wfc_error_msg( lang.label('messege_reload') );
		}
}


// If it is table layout, the width and height must be adjusted.     
function wfc_layout_adjust_box_property(the_boxObject)
{
    if (the_boxObject == null) return;
    if (!wfc_is_table_layout_style(currTabLayout)) return;  // not table layout style.

    // get related boxes size.   
    var parentBoxSize = the_boxObject.getParent().getSize();		 
    var boxChildren = the_boxObject.getChildren();
    var s0 = boxChildren[0].getSize();
    var s1 = boxChildren[1].getSize();
    var s2 = boxChildren[2].getSize();
    // height = parent box height - title_block - footer_block - 12.
    // top margin:4 + bottom margin 4 + box border 4
    var NewContentBoxHeight=parentBoxSize.y - s0.y - s2.y - 12;
    if(!boxChildren[1].style.height && NewContentBoxHeight>0) {
        boxChildren[1].setStyle('height', NewContentBoxHeight);  
    }	
    var w = the_boxObject.getParent().getSize().x;
    the_boxObject.setStyle('width', w-4);
    
    boxChildren[1].setStyle('overflow', 'hidden');
    
}

// given an array, return how many defined entities count.
function wfc_get_defined_entity(ar)
{
    if (ar == undefined) return 0;
    if (ar.length <=0 ) return 0;
    var count = 0;
    ar.each(function(module, id)
    {  
	    if(module !=undefined && module !="" && module !='undefined')
	        count++;
	});
	return count;
}

// get next available block, if all full, return td_id+0.
function wfc_get_next_available_block(tb, td_id)
{
    var result = undefined;
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
         result = tb.getElementById(td_id + '' + iIndex);
         if (!$defined(result)) break;
         // check how many sbox in this result.
         var xTemp = result.getElements('div[id^=sbox]');
         if (xTemp.length == 0) return result;  // empty block.
    }
    if ($defined(result)) return result;
    // not found; return null
    //result = $(td_id + '' + 0);
    return result;
}

function wfc_inject_one_widget_and_set(el, target, original_height)
{
    // Inject el to target
    el.injectInside(target);
    el.setStyle('position','relative');
	el.setStyle('left','0px');
	el.setStyle('top','0px');
    el.setStyle('width','100%');
	el.setStyle('zIndex','0');

    // reset the height.
    var boxChildren = el.getChildren();
    var s0 = boxChildren[0].getSize();
    var s1 = boxChildren[1].getSize();
    var s2 = boxChildren[2].getSize();
    
    el.setStyle('height', original_height - 12);
    boxChildren[1].setStyle('height', original_height - s0.y - s2.y - 12);	
}

// inject a widget el to empty block (target); after inject, need some settings
// if the target has a widget, discard it
function wfc_inject_widget_to_block(el, target)
{
    if (target.getElements('div[id^=sbox]').length > 0) return; // it's not a empty block
    
    var original_height = target.getSize().y;   // memorized it before inject, ensure the height no changed

    // Inject el to target
    el.injectInside(target);
    el.setStyle('position','relative');
	el.setStyle('left','0px');
	el.setStyle('top','0px');
    el.setStyle('width','100%');
	el.setStyle('zIndex','0');

    // reset the height.
    var boxChildren = el.getChildren();
    var s0 = boxChildren[0].getSize();
    var s1 = boxChildren[1].getSize();
    var s2 = boxChildren[2].getSize();
    
    el.setStyle('height', original_height - 12);
    boxChildren[1].setStyle('height', original_height - s0.y - s2.y - 12);	
}

function wfc_set_calculated_cell_height(table)
{
		var vertical_scroll = 18;
		var page_header_menu =25;
		var floter = 60;
    var rows=	 table.getElements('tr');
    var browserheight=document.body.clientHeight-page_header_menu-floter-vertical_scroll;
    rows.each(function(tr,trcount){
    	var columns=tr.getElements('td');
    	columns.each(function(td,tdcount){
    		 
    		  var cellheight=td.getStyle('height');
    		  if(cellheight.indexOf('%')>-1)
    		  {
    		  	var myheight=cellheight.replace(/%/i,'');
      			td.setStyle('height',myheight*browserheight/100+'px');
      		}
      });
    });		
}

// change layout, from one table to another table style
function wfc_adjust_settings(mid , ttl, layout) 
{
    var layout = wfc_getSelectedLayout();
    var table_html_text = wfc_ajax_read_table_layout_file(layout);
    if (!$defined(table_html_text)) return; // unable to read the table file.

	currTabLayout = layout; 
    pageNumber = mid;				

    // read new layout file OK.
    // create a temp div and insert the read in table 
    var new_tb = new Element('div', {'id':'TempTable'+mid});
    var old_tb = $('contenttable'+mid);
		new_tb.setHTML(table_html_text);
		wfc_set_calculated_cell_height(new_tb);
    new_tb.injectBefore(old_tb);		    
    var tb_children = new_tb.getChildren();
    tb_children[0].id = 'TableLayout'+mid;

    // parse all widgets in old_tb.    
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
        var c_string = "cttd" + mid + iIndex;
        var e0 = $(c_string);
        if (!$defined(e0)) break;   // no more blocks.
        // get all widgets in this block
        var xTemp = e0.getElements('div[id^=sbox]');
        for(var u=0; u<xTemp.length; u++) {
            var available_block = wfc_get_next_available_block(new_tb, 'c');
            if ($defined(available_block)) {
                // find an empty block, inject it to new block.
                wfc_inject_widget_to_block(xTemp[u], available_block);
            }
        }
    }
    
    // change the name of old table.
    old_tb.remove();
    old_tb.destroy();
    
    wfc_change_table_id(new_tb, mid);
    
    new_tb.id = 'contenttable'+mid;
    
	/// save user data
	saveUD();						
}

// after read in table layout HTML file, replace <TD> <TR> <TBODY> with proper id
function wfc_change_table_id(tb, nPageNumber)
{
    var tb_children = tb.getChildren();
    tb_children[0].id = 'TableLayout'+nPageNumber;
    
    // must replace all the cell ide to cttd+page_number+id
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
         var c_string = "c" + iIndex;
         var cx = tb.getElementById(c_string);
         if (!$defined(cx)) break;
         cx.id = "cttd" + nPageNumber + iIndex;
    }
    var bx = tb.getElementById('b');
    if ($defined(bx)) bx.id = 'cttbd'+nPageNumber;
}

// given 2 coordinates, test if pos1 (center) is inside pos2 
function wfc_position_inside(pos1, pos2)
{
    var center_x = pos1.left + pos1.width/2;
    if (center_x < pos2.left) return false;
    if (center_x > pos2.right) return false;
    var center_y = pos1.top;    //  + pos1.height/2;
    if (center_y < pos2.top) return false;
    if (center_y > pos2.bottom) return false;
    return true;
}

// given a pos (position), test which block is it in.
function wfc_hit_test(pos)
{
    // traverse all blocks.
    for (var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
        var c_string = "cttd" +  wfc_mainScreen.currActive + iIndex;
        var cx = $(c_string);
        if (!$defined(cx)) break;
        if (wfc_position_inside(pos, cx.getCoordinates()))
            return cx;
    }
    return null;
}

// if it is table layout style, return the cliehtHeight, else return 0 (not defined)
function wfc_getBoxHeight(el)
{
	if (el.boxObject == null)
		return 0;
	if (wfc_is_table_layout_style(currTabLayout))
	    return el.boxObject.getParent().clientHeight;
	return 0;
}

function wfc_reset_all_widget_border()
{
    for(var iIndex=0; iIndex<wfc_widgetLimit; iIndex++) {
        var c_string = "cttd" + wfc_mainScreen.currActive + iIndex;
        var e0 = $(c_string);
        if (!$defined(e0)) break;
        
        // check if e0 contains a DIV with id starts with sbox
        var xTemp = e0.getElements('div[id^=sbox]');
        if (xTemp.length > 0) {
            xTemp[0].setStyle('border', '1px solid #999999');
        }
    }
}

// start drag an element
function wfc_drag_box()
{
    dragstep++; 
	if(dragging && dragstep%4==0){ 
		var pos = $(dragwhich).getCoordinates();
		var dest = wfc_hit_test(pos);
		if (dest == null) return;
		
        var tempp = $('temppp'+dragwhich);
		if (!$defined(tempp)) return;    // can't find the temp box.
        var temp_dragwhich_parent = tempp.getParent();
        if (dest.id == temp_dragwhich_parent.id) return;    // same block.

        // different block, restore previous tempp border to normal
        var the_boxObjectArray = temp_dragwhich_parent.getElements('div[id^=sbox]');
        if (the_boxObjectArray.length > 0) {
            the_boxObjectArray[0].setStyle('border', '1px solid #999999');
        }
        
        // move the temp_box to dest.
        tempp.setStyle('width', dest.getSize().x - 4);
        tempp.setStyle('height', dest.getSize().y - 12);
        
        // if the dest has a widget in it, make tempp invisible        
		the_boxObjectArray = dest.getElements('div[id^=sbox]');
		if ((the_boxObjectArray.length <= 0) || (dest.id == $(dragwhich).getParent().id)) {
		    tempp.setStyle('display', 'block');
		}
		else {
		    tempp.setStyle('display', 'none');
		    the_boxObjectArray[0].setStyle('border', '1px dotted red');
		}
		
        $('temppp'+dragwhich).injectInside(dest);
        dragtarget = dest;
	}
}

// set back the drop el styles.
function wfc_after_drop_normal_settings(el)
{
    // change the stlye back to normal.
	el.setStyle('position','relative');
	el.setStyle('left','0px');
	el.setStyle('top','0px');
    el.setStyle('width','100%');
	el.setStyle('zIndex','0');

    var tbl = el.id.replace(/sbox/i , '');
    $('insettbl'+tbl).fireEvent('mouseout');

	el.setStyle('zIndex','0');
	dragging = false; dragwhich=null; dragcord = null;dragtarget=null;dragstep=0;
}

// when widget drag drop to a place already has widget in it.
// hide the destion widget first, then move the src widget to destination.
// Then must move the destination widget to src block.
var wfc_widget_exchange_src_id = null;     // the source widget id, 
var wfc_widget_exchange_dst_id = null;     // the destination block id.
function wfc_widget_exchange()
{
//    debugger;
    if (wfc_widget_exchange_src_id == null) return;
    if (wfc_widget_exchange_dst_id == null) return;
    
    // remember the source block.
    var src = $(wfc_widget_exchange_src_id).getParent().id;
    var original_height = $(wfc_widget_exchange_dst_id).getSize().y;   // memorized it before inject, ensure the height no changed
    
    // inject to new position
    var el = $(wfc_widget_exchange_src_id);
    el.injectInside($(wfc_widget_exchange_dst_id));
    el.setStyle('display', 'block');        // it was hidden, display it.
    
    // adjust the width and styles    
	el.setStyle('position','relative');
	el.setStyle('left','0px');
	el.setStyle('top','0px');
    el.setStyle('width','100%');
	el.setStyle('zIndex','0');
    
    // adjust the height
    var boxChildren = el.getChildren();
    var s0 = boxChildren[0].getSize();
    var s1 = boxChildren[1].getSize();
    var s2 = boxChildren[2].getSize();
 
    el.setStyle('height', original_height - 12);
    boxChildren[1].setStyle('height', original_height - s0.y - s2.y - 12);	
        
    el.fireEvent('AfterDrop', [src, wfc_widget_exchange_dst_id], 100);   
    
    wfc_widget_exchange_src_id = null;
    wfc_widget_exchange_dst_id = null;
    //delay some time to prepare udata information
    setTimeout("saveUD()" , 100);
}


// In table layout style, after user drop, call this function.
function wfc_drop_complete(el)
{
    if (dragwhich == null) return;
    var src = $(dragwhich).getParent().id;
    var tmp = $('temppp'+dragwhich);
    
    // avoid errors when click a icon and start dragging at the same time
    if(!tmp) {
        iambz = false; 
        return; 
    }
    
    var dst = tmp.getParent().id;

    // remove the temp red box    
	if($defined($('temppp'+dragwhich))) 
	    $('temppp'+dragwhich).remove();

    // sometimes some widgets border become red dot lines whild dragging. set them back.
    wfc_reset_all_widget_border();  
    
    if (src == dst) {   // source and destion are the same, no update.
        wfc_after_drop_normal_settings(el);
        iambz = false;  // because this didn't call saveUD(); must let IamBusy = false.
        return;   
    }
    
    // src != dst.
    var target = $(dst);
    var dstWidgetArray = target.getElements('div[id^=sbox]');
    if (dstWidgetArray.length <= 0) {
        // dst is an empty block, just inser it
        var original_height = target.getSize().y;   // memorized it before inject, ensure the height no changed
 
        // Inject el to target
        el.injectInside(target);
        wfc_after_drop_normal_settings(el);
        
        // reset the height.
        var boxChildren = el.getChildren();
        var s0 = boxChildren[0].getSize();
        var s1 = boxChildren[1].getSize();
        var s2 = boxChildren[2].getSize();
    
        el.setStyle('height', original_height - 12);
        boxChildren[1].setStyle('height', original_height - s0.y - s2.y - 12);	
        
        el.fireEvent('AfterDrop', [src, dst], 100);   
    	setTimeout("saveUD()" , 100);
        //return;
    }    
    else {   
        // src != dst and det has a widget in it.
        var original_height = target.getSize().y;   // memorized it before inject, ensure the height no changed
        // get the target widget, hide it.
        var w0 = dstWidgetArray[0];
        w0.setStyle('display', 'none');
        
        // Inject el to target
        el.injectInside(target);
        wfc_after_drop_normal_settings(el);
        
        // reset the height.
        var boxChildren = el.getChildren();
        var s0 = boxChildren[0].getSize();
        var s1 = boxChildren[1].getSize();
        var s2 = boxChildren[2].getSize();
    
        el.setStyle('height', original_height - 12);
        boxChildren[1].setStyle('height', original_height - s0.y - s2.y - 12);	
        
        el.fireEvent('AfterDrop', [src, dst], 100);  
        
        // move the target widget to src.
        wfc_widget_exchange_src_id = w0.id;     // destination becomes src
        wfc_widget_exchange_dst_id = src;       // src becomes destination
		setTimeout("wfc_widget_exchange()", 200);
         
        //return;
    }
    /*
        				if($defined( $('temppp'+mydragwhich) ) ) {
        					    $('temppp'+mydragwhich).remove();
					    }

        				if (mydragwhich != null) {
   			    			// Terrence 03/27/09; add [src, dst] to afterDrop signal.
        				    var dst = null;
   	    		    		var src = $(mydragwhich).parentNode.id;
					        if(this.innerHTML == "&nbsp;") this.setHTML(""); 
					
       						// decide where to insert; maybe no place change. (no inject)
	        				if(cloneinside != undefined){   
			        			dst = cloneinside;
					        	el.injectInside(cloneinside);
       						}else if(cloneover != undefined){
	        					dst = $(cloneover).parentNode.id;
			        			el.injectBefore(cloneover);
					        }else if(cloneunder != undefined){
       							dst = $(cloneunder).parentNode.id;;
	        					el.injectAfter(cloneunder);
			        		}
       						// change the stlye back to normal.
	        				el.setStyle('position','relative');
			        		el.setStyle('left','0px');
					        el.setStyle('top','0px');
       						el.setStyle('width','100%');
	        				el.setStyle('zIndex','0');

       						var tbl = el.id.replace(/sbox/i , '');
        					$('insettbl'+tbl).fireEvent('mouseout');
	        				// Terrence 03/27/09; user defined event for widget handler to redraw.
		        			// src: source column; dst: destination column.
			        		if (dst != null) {
				    	       el.fireEvent('AfterDrop', [src, dst], 100);   
				    	    }
				        } // end of if (dragwhich != null);
					//
					setTimeout("saveUD()" , 100);
					// onComplete, (in Mootools 1.2, it won't fire onComplete event). clean up
					el.setStyle('zIndex' ,'0'); 
					dragging = false;dragwhich=null; dragcord = null;dragtarget=null;dragstep=0;
                    
                    // Jeff Huang 10/06/09
                    // To fix z-index issue:
                    // we will fire an event in the end of dropping
                    el.fireEvent('onEndDrop', 50);  
    */                    
}

// end of table style layout
//////////////////////////////////////////////////////////////////////////////////
